<template>
  <div class="knowledge-container">
    <!-- 知识库分类 -->
    <el-row :gutter="20">
      <el-col :span="6">
        <el-card shadow="hover" class="category-card">
          <template #header>
            <div class="card-header">
              <span>知识分类</span>
              <el-button type="primary" size="small" plain @click="addCategory">
                <el-icon><Plus /></el-icon>添加分类
              </el-button>
            </div>
          </template>
          <el-menu
            :default-active="activeCategory"
            class="category-menu"
            @select="handleCategorySelect"
          >
            <el-menu-item v-for="category in categories" :key="category.categoryId" :index="category.categoryId.toString()">
              <el-icon><Folder /></el-icon>
              <!-- <span>{{ category.categoryName }}</span> -->
              <template #title>
                <span>{{ category.categoryName }}</span>
                <!-- <span class="item-count">({{ category.itemCount }})</span> -->
              </template>
            </el-menu-item>
          </el-menu>
        </el-card>
      </el-col>

      <el-col :span="18">
        <el-card shadow="hover" class="content-card">
          <template #header>
            <div class="card-header">
              <div class="header-left">
                <span>{{ currentCategoryName }}内容管理</span>
                <el-tag type="info" size="small" class="count-tag">共 {{ totalItems }} 项</el-tag>
              </div>
              <div class="header-operations">
                <el-select v-model="contentType" placeholder="内容类型" size="small" style="width: 120px; margin-right: 10px;">
                  <el-option label="全部" value="" />
                  <el-option label="视频" value="video" />
                  <el-option label="文档" value="document" />
                  <el-option label="图片" value="image" />
                  <el-option label="问答题" value="quiz" />
                </el-select>
                <el-button type="primary" plain @click="addContent">
                  <el-icon><Plus /></el-icon>添加内容
                </el-button>
              </div>
            </div>
          </template>

          <!-- 内容列表 -->
          <el-table
            :data="contentList"
            style="width: 100%"
            border
            stripe
            v-loading="loading"
          >
            <el-table-column prop="contentId" label="ID" width="80" />
            <el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip />
            <el-table-column prop="contentType" label="类型" width="100">
              <template #default="scope">
                <el-tag :type="getContentTypeTag(scope.row.contentType)" size="small">
                  {{ getContentTypeName(scope.row.contentType) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="createdAt" label="创建时间" width="180" />
            <el-table-column prop="updatedAt" label="更新时间" width="180" />
            <el-table-column label="操作" fixed="right" width="250">
              <template #default="scope">
                <el-button size="small" type="primary" @click="editContent(scope.row)">
                  编辑
                </el-button>
                <el-button size="small" type="success" @click="previewContentHandler(scope.row)">
                  预览
                </el-button>
                  
                <el-button size="small" type="danger" @click="deleteContent(scope.row)">
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <div class="pagination-container">
            <el-pagination
              v-model:current-page="currentPage"
              v-model:page-size="pageSize"
              :page-sizes="[10, 20, 50, 100]"
              layout="total, sizes, prev, pager, next, jumper"
              :total="totalItems"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 添加/编辑分类对话框 -->
    <el-dialog
      v-model="categoryDialogVisible"
      :title="isEdit ? '编辑分类' : '添加分类'"
      width="30%"
    >
      <el-form :model="categoryForm" label-width="80px">
        <el-form-item label="分类名称">
          <el-input v-model="categoryForm.categoryName" placeholder="请输入分类名称" />
        </el-form-item>
        <!-- <el-form-item label="数量">
          <el-input-number v-model="categoryForm.itemCount" :min="0" :max="100" />
        </el-form-item> -->
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="categoryDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveCategory">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 添加/编辑内容对话框 -->
    <el-dialog
      v-model="contentDialogVisible"
      :title="isEdit ? '编辑内容' : '添加内容'"
      width="60%"
    >
      <el-form :model="contentForm" label-width="100px">
        <el-form-item label="标题">
          <el-input v-model="contentForm.title" placeholder="请输入内容标题" />
        </el-form-item>
        <el-form-item label="内容类型">
          <el-select v-model="contentForm.type" placeholder="请选择内容类型" style="width: 100%">
            <el-option label="视频" value="video" />
            <el-option label="文档" value="document" />
            <el-option label="图片" value="image" />
            <el-option label="问答题" value="quiz" />
          </el-select>
        </el-form-item>

        <!-- 视频内容 -->
        <template v-if="contentForm.type === 'video'">
          <el-form-item label="视频文件">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleVideoChange"
              accept="video/*"
              :limit="1"
              ref="videoUpload"
            >
              <el-button type="primary">选择视频文件</el-button>
            </el-upload>
          </el-form-item>
        </template>

        <!-- 文档内容 -->
        <template v-if="contentForm.type === 'document'">
          <el-form-item label="文档上传">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleDocumentChange"
              accept=".pdf,.doc,.docx,.ppt,.pptx"
              ref="documentUpload"
            >
              <el-button type="primary">选择文档</el-button>
              <template #tip>
                <div class="el-upload__tip">支持 PDF、Word、PPT 等格式</div>
              </template>
            </el-upload>
          </el-form-item>
        </template>

        <!-- 图片内容 -->
        <template v-if="contentForm.type === 'image'">
          <el-form-item label="图片上传">
            <el-upload
              :auto-upload="false"
              :show-file-list="true"
              :on-change="handleImageChange"
              :on-remove="handleImageRemove"
              list-type="picture-card"
              :limit="1"
              ref="imageUpload"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
          </el-form-item>
        </template>

        <!-- 问答题内容 -->
        <template v-if="contentForm.type === 'quiz'">
          <el-form-item label="题目">
            <el-input
              v-model="contentForm.question"
              type="textarea"
              :rows="3"
              placeholder="请输入题目内容"
            />
          </el-form-item>
          <el-form-item label="选项">
            <div v-for="(option, index) in contentForm.options" :key="index" class="option-item">
              <el-radio v-model="contentForm.correctAnswer" :label="index">正确答案</el-radio>
              <el-input v-model="contentForm.options[index]" placeholder="请输入选项内容" />
              <el-button type="danger" icon="Delete" circle @click="removeOption(index)" />
            </div>
            <el-button type="primary" plain @click="addOption">添加选项</el-button>
          </el-form-item>
          <el-form-item label="解析">
            <el-input
              v-model="contentForm.explanation"
              type="textarea"
              :rows="3"
              placeholder="请输入题目解析"
            />
          </el-form-item>
        </template>

        <!-- 通用描述 -->
        <el-form-item label="描述">
          <el-input
            v-model="contentForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入内容描述"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="contentDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveContent">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 内容预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      :title="previewContent.title || '内容预览'"
      width="70%"
    >
      <div v-loading="loading" class="preview-container">
        <!-- 视频预览 -->
        <template v-if="previewContent.type === 'video'">
          <div class="video-container">
            <video
              @error="handleMediaError('video')"
              controls
              class="preview-video"
              :src="previewContent.videoUrl"
              :poster="previewContent.coverUrl"
            ></video>
          </div>
        </template>

        <!-- 文档预览 -->
<template v-if="previewContent.type === 'document'">
  <div class="document-container">
    <!-- 文本文件特殊处理 -->
    <div v-if="previewContent.isTextFile" class="text-preview">
      <div class="text-content-preview" v-if="previewContent.textContent">
        {{ previewContent.textContent }}
      </div>
      <div v-else class="no-document">
        <el-alert type="info" show-icon>
          文本内容为空
        </el-alert>
      </div>
    </div>
    
    <!-- 非文本文件使用iframe预览 -->
    <iframe
      v-else-if="previewContent.documentUrl"
      class="preview-document"
      :src="previewContent.documentUrl"
      @error="handleMediaError('document')"
      frameborder="0"
    ></iframe>
    
    <!-- 备用显示方案 -->
    <div v-else class="no-document">
      <el-alert type="info" show-icon>
        无法预览文档，请尝试下载查看
        <el-button type="primary" size="small" @click="downloadDocument(previewContent.contentId)">下载文档</el-button>
      </el-alert>
      <div class="text-content-preview" v-if="previewContent.textContent">
        {{ previewContent.textContent }}
      </div>
    </div>
  </div>
</template>

        <!-- 图片预览 -->
        <template v-if="previewContent.type === 'image'">
          <div class="image-container">
            <el-carousel :interval="4000" type="card" height="400px">
              <el-carousel-item v-for="(img, index) in previewContent.images" :key="index">
                <img :src="img" class="preview-image" @error="handleImageError" />
              </el-carousel-item>
            </el-carousel>
          </div>
        </template>

        <!-- 问答题预览 -->
        <template v-if="previewContent.type === 'quiz'">
          <div class="quiz-container">
            <h3 class="quiz-question">{{ previewContent.question }}</h3>
            <el-radio-group v-model="selectedAnswer" class="quiz-options">
              <div v-for="(option, index) in previewContent.options" :key="index" class="quiz-option">
                <el-radio :label="index">{{ option }}</el-radio>
              </div>
            </el-radio-group>
            <div class="quiz-result" v-if="showQuizResult">
              <div :class="['result-message', isCorrect ? 'correct' : 'incorrect']">
                {{ isCorrect ? '回答正确！' : '回答错误！' }}
              </div>
              <div class="explanation">
                <h4>解析：</h4>
                <p>{{ previewContent.explanation }}</p>
              </div>
            </div>
            <el-button type="primary" @click="checkAnswer(selectedAnswer)" v-if="!showQuizResult">提交答案</el-button>
            <el-button type="info" @click="resetQuiz" v-else>重新作答</el-button>
          </div>
        </template>

        <div class="preview-info">
          <h4>内容描述：</h4>
          <p>{{ previewContent.description }}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'
import { API_BASE_URL } from '@/utils/constants'

// MIME类型到文件扩展名的映射
const MIME_TYPE_TO_EXTENSION = {
  'application/pdf': '.pdf',
  'application/msword': '.doc',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': '.docx',
  'application/vnd.ms-powerpoint': '.ppt',
  'application/vnd.openxmlformats-officedocument.presentationml.presentation': '.pptx',
  'application/vnd.ms-excel': '.xls',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': '.xlsx',
  'text/plain': '.txt',
  'text/markdown': '.md',
  'image/jpeg': '.jpg',
  'image/png': '.png',
  'image/gif': '.gif',
  'application/zip': '.zip',
  'application/x-rar-compressed': '.rar'
};

// ================== 分类相关 ==================
const activeCategory = ref('1')
const categories = ref([])

// ================== 内容相关 ==================
const contentType = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const loading = ref(false)
const contentList = ref([])
const totalItems = ref(0)

const currentCategoryName = computed(() => {
  const category = categories.value.find(c => c.categoryId.toString() === activeCategory.value)
  return category ? category.categoryName : '全部'
})

// ================== 分类对话框 ==================
const categoryDialogVisible = ref(false)
const isEdit = ref(false)
const categoryForm = reactive({
  categoryName: '',
  itemCount: 0
})

// ================== 内容对话框 ==================
const contentDialogVisible = ref(false)

// 内容表单（仅元数据）
const contentForm = reactive({
  title: '',
  type: 'video',
  question: '',
  options: ['', '', '', ''],
  correctAnswer: 0,
  explanation: '',
  description: ''
})

// 文件缓存
const fileFields = {
  videoFile: null,
  coverFile: null,
  documentFile: null,
  imageFile: null // 只存储单个图片文件
}

// 清空文件缓存
const resetFileFields = () => {
  fileFields.videoFile = null
  fileFields.coverFile = null
  fileFields.documentFile = null
  fileFields.imageFile = null
}

// 通用文件处理函数
const handleFileChange = (file, type) => {
  switch (type) {
    case 'video':
      fileFields.videoFile = file.raw || file
      ElMessage.success('视频文件已选择')
      break
    case 'document':
      fileFields.documentFile = file.raw || file
      ElMessage.success('文档已选择')
      break
    case 'image':
      fileFields.imageFile = file.raw || file
      ElMessage.success('图片已选择')
      break
  }
}

// ================== 上传事件处理 ==================
const handleVideoChange = (file) => {
  if (file && file.raw) {
    fileFields.videoFile = file.raw
    ElMessage.success('视频文件已选择')
  } else if (file) {
    fileFields.videoFile = file
    ElMessage.success('视频文件已选择')
  }
}

const handleDocumentChange = (file) => {
  if (file && file.raw) {
    fileFields.documentFile = file.raw
    ElMessage.success('文档已选择')
  } else if (file) {
    fileFields.documentFile = file
    ElMessage.success('文档已选择')
  }
}

const handleImageChange = (file) => {
  if (file && file.raw) {
    fileFields.imageFile = file.raw // 只存储单个文件
    ElMessage.success('图片已选择')
  } else if (file) {
    fileFields.imageFile = file
    ElMessage.success('图片已选择')
  }
}

const handleImageRemove = () => {
  fileFields.imageFile = null
}

// ================== 保存内容 ==================
const saveContent = async () => {
  if (!contentForm.title.trim()) {
    ElMessage.warning('请输入内容标题')
    return
  }

  // 问答题校验
  if (contentForm.type === 'quiz') {
    if (!contentForm.question.trim()) {
      ElMessage.warning('请输入题目内容')
      return
    }
    const hasEmptyOption = contentForm.options.some(opt => !opt.trim())
    if (hasEmptyOption) {
      ElMessage.warning('请填写所有选项内容')
      return
    }
  }

  // 构造 FormData
  const formData = new FormData()

  // 修改字段名以匹配后端 KnowledgeContent 对象属性名
  formData.append('title', contentForm.title)
  formData.append('description', contentForm.description || '')

  // 映射 contentType 到数据库枚举值
  let contentTypeValue = ''
  switch (contentForm.type) {
    case 'video':
      contentTypeValue = 'video'
      break
    case 'document':
      contentTypeValue = 'document'
      break
    case 'image':
      contentTypeValue = 'image'
      break
    case 'quiz':
      contentTypeValue = 'quiz'
      break
    default:
      contentTypeValue = 'document'
  }
  formData.append('contentType', contentTypeValue)

  // 添加 textContent 字段（用于文档和问答题）
  if (contentForm.type === 'document') {
    // const textContent = `${contentForm.title}\n${contentForm.description || ''}`
    // formData.append('textContent', textContent)
     if (fileFields.documentFile && /\.(txt|md)$/.test(fileFields.documentFile.name)) {
    try {
      const text = await fileFields.documentFile.text();
      formData.append('textContent', text);
    } catch (e) {
      console.error('文本文件读取失败:', e);
      const fallbackText = `${contentForm.title}\n${contentForm.description || ''}`;
      formData.append('textContent', fallbackText);
    }}
  } else if (contentForm.type === 'quiz') {
    const fullText = [
      `题目：${contentForm.question}`,
      `选项：${contentForm.options.filter(o => o).join('； ')}`,
      `正确答案：${contentForm.options[contentForm.correctAnswer]}`,
      `解析：${contentForm.explanation}`
    ].join('\n')
    formData.append('textContent', fullText)
  } else {
    // formData.append('textContent', '') // 其他类型留空
     const fallbackText = `${contentForm.title}\n${contentForm.description || ''}`;
    formData.append('textContent', fallbackText);
  }

  // 使用正确的字段名 categoryId
  formData.append('categoryId', activeCategory.value)

  // 添加文件（确保所有类型都以'file'字段名发送）
  if (contentForm.type === 'image' && fileFields.imageFile) {
    formData.append('file', fileFields.imageFile)
  } else if (contentForm.type === 'video' && fileFields.videoFile) {
    formData.append('file', fileFields.videoFile)
  } else if (contentForm.type === 'document' && fileFields.documentFile) {
    formData.append('file', fileFields.documentFile)
  } else if (contentForm.type === 'quiz') {
    const quizText = [
      `题目：${contentForm.question}`,
      `选项：${contentForm.options.filter(o => o.trim()).join(' | ')}`,
      `正确答案：${contentForm.options[contentForm.correctAnswer]}`,
      `解析：${contentForm.explanation || '无'}`
    ].join('\n');

    const quizBlob = new Blob([quizText], { type: 'text/plain' });
    formData.append('file', quizBlob, 'quiz-content.txt');
  } else if (contentForm.type !== 'quiz') {
    ElMessage.warning('请选择要上传的文件')
    return
  }
  
  try {
    const response = await axios.post(
      `${API_BASE_URL}/knowledge-contents/add`,
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        timeout: 300000
      }
    )
    if (response.data.code === 1) {
      ElMessage.success('内容上传成功')
      contentDialogVisible.value = false
      fetchContentList()
      resetFileFields()
    } else {
      ElMessage.error(response.data.msg || '提交失败')
    }
  } catch (error) {
    ElMessage.error('上传失败：' + (error.message || '网络错误'))
    console.error('Upload error:', error)
  }
}

// ================== 编辑内容 ==================
const editContent = (content) => {
  isEdit.value = true
  // 注意：假设后端返回的数据字段也已对齐（如 content_type, text_content 等）
  Object.assign(contentForm, {
    title: content.title,
    description: content.description,
    // 注意：这里假设 content.type 已被转换为 'video'/'document' 等用于前端显示
    // 实际应从 content.content_type 映射回来
    type: mapContentTypeToForm(content.content_type),
    question: content.question || '',
    options: content.options || ['', '', '', ''],
    correctAnswer: content.correctAnswer || 0,
    explanation: content.explanation || ''
  })
  resetFileFields()
  contentDialogVisible.value = true
}

// 辅助函数：将数据库 content_type 映射回前端表单的 type
const mapContentTypeToForm = (dbType) => {
  switch (dbType) {
    case '视频': return 'video'
    case '图片': return 'image'
    case '问答题': return 'quiz'
    case '文本': return 'document'
    default:
      return 'document'
  }
}

// ================== 添加选项 ==================
const addOption = () => {
  contentForm.options.push('')
}

const removeOption = (index) => {
  if (contentForm.options.length <= 2) {
    ElMessage.warning('至少需要两个选项')
    return
  }
  contentForm.options.splice(index, 1)
  if (contentForm.correctAnswer >= contentForm.options.length) {
    contentForm.correctAnswer = 0
  }
}

// ================== 添加内容 ==================
const addContent = () => {
  isEdit.value = false
  Object.assign(contentForm, {
    title: '',
    type: 'video',
    question: '',
    options: ['', '', '', ''],
    correctAnswer: 0,
    explanation: '',
    description: ''
  })
  resetFileFields()
  contentDialogVisible.value = true
}

// ================== 预览与删除 ==================
const previewDialogVisible = ref(false)
const previewContent = ref({})
const selectedAnswer = ref(null)
const showQuizResult = ref(false)
const isCorrect = ref(false)

// 辅助函数：从Content-Disposition头解析文件名
const parseFileNameFromHeader = (contentDisposition) => {
  if (!contentDisposition) return null;
  
  // 处理格式1: attachment; filename="example.pdf"
  let matches = contentDisposition.match(/filename\s*=\s*"([^"]+)"/);
  if (matches && matches[1]) {
    return matches[1];
  } 
  
  // 处理格式2: attachment; filename=example.pdf
  matches = contentDisposition.match(/filename\s*=\s*([^;]+)/);
  if (matches && matches[1]) {
    return matches[1].trim();
  }
  
  // 处理格式3: attachment; filename*=UTF-8''example.pdf
  matches = contentDisposition.match(/filename\*=\s*[^']+'[^']*'([^;]+)/);
  if (matches && matches[1]) {
    return decodeURIComponent(matches[1]);
  }
  
  return null;
};

// 辅助函数：确保文件名有正确的扩展名
const ensureFileExtension = (fileName, contentType) => {
  // 如果文件名已经包含扩展名，返回原文件名
  if (fileName.includes('.') && fileName.split('.').pop().length <= 4) {
    return fileName;
  }
  
  // 根据Content-Type添加扩展名
  const extension = MIME_TYPE_TO_EXTENSION[contentType];
  if (extension) {
    return fileName + extension;
  }
  
  // 默认扩展名
  return fileName + '.file';
};

// 获取内容详情
// 替换原有的 fetchContentDetail 函数
const fetchContentDetail = async (id) => {
  try {
    // 严格检查 ID
    if (!id) {
      throw new Error('无效的内容ID')
    }
    
    const url = `${API_BASE_URL}/knowledge-contents/${id}`
    console.log('【预览】开始请求内容详情:', url)
    
    const response = await axios.get(url, {
      timeout: 15000,
      headers: {
        'Accept': 'application/json',
        'Cache-Control': 'no-cache'
      }
    })
    
    console.log('【预览】内容详情响应状态:', response.status)
    
    if (response.data.code !== 1) {
      throw new Error(response.data.msg || `请求失败 (状态码: ${response.data.code})`)
    }
    
    if (!response.data.data) {
      throw new Error('服务器返回数据为空')
    }
    
    // 详细记录返回的数据结构
    console.log('【预览】内容详情数据:', {
      contentType: response.data.data.contentType,
      fileUrl: response.data.data.fileUrl,
      coverUrl: response.data.data.coverUrl,
      // ...其他字段
    })
    
    return response.data.data
  } catch (error) {
    console.error('【预览】获取内容详情失败:', {
      message: error.message,
      code: error.code,
      response: error.response ? {
        status: error.response.status,
        data: error.response.data
      } : null
    })
    
    let errorMessage = '获取内容详情失败'
    
    if (error.message.includes('timeout')) {
      errorMessage = '请求超时，请检查网络连接'
    } 
    else if (error.code === 'ERR_NETWORK') {
      errorMessage = '无法连接到服务器，请检查服务是否正常运行'
    }
    else if (error.response) {
      const status = error.response.status
      const errorMsg = error.response.data?.msg || '未知错误'
      
      if (status === 404) {
        errorMessage = '内容不存在或已被删除'
      } 
      else if (status === 401 || status === 403) {
        errorMessage = '没有权限访问该内容'
      }
      else {
        errorMessage = `服务器错误 (${status}): ${errorMsg}`
      }
    }
    
    ElMessage.error({
      message: errorMessage,
      duration: 5000,
      showClose: true
    })
    
    throw error
  }
}

// 预览内容处理
// 替换原有的 previewContentHandler 函数
const previewContentHandler = async (content) => {
  try {
    if (!content || !content.contentId) {
      ElMessage.error('内容信息不完整，无法预览')
      return
    }

    loading.value = true
    console.log('【预览】开始预览内容:', content)
    
    try {
      // 1. 首先获取内容详情
      const detail = await fetchContentDetail(content.contentId)
      if (!detail) {
        throw new Error('无法获取内容详情')
      }
      
      // 2. 根据内容类型决定是否需要单独获取文件
      let fileBlob = null
// 添加 'document' 类型到条件判断中
if (detail.contentType === 'video' || detail.contentType === 'image' || detail.contentType === 'document') {
  try {
    console.log(`【预览】开始获取${detail.contentType}文件数据...`)
    fileBlob = await fetchContentFile(content.contentId)
    console.log('【预览】成功获取文件数据:', fileBlob)
  } catch (fileError) {
    console.warn(`【预览】获取${detail.contentType}文件数据失败:`, fileError)
    // 即使文件获取失败，也继续使用元数据中的URL
  }
}
      
      // 3. 处理预览数据，传入文件Blob
      const previewData = processPreviewData(detail, fileBlob)
      console.log('【预览】处理后的预览数据:', previewData)
      previewContent.value = previewData
      selectedAnswer.value = null
      showQuizResult.value = false
      previewDialogVisible.value = true
      console.log('【预览】成功加载预览数据:', previewData)
      
    } catch (error) {
      console.error('【预览】预览处理错误:', error)
      ElMessage.error(`预览失败: ${error.message || '未知错误'}`)
    }
  } catch (error) {
    console.error('【预览】预览过程中发生意外错误:', error)
    ElMessage.error('预览处理失败，请查看控制台日志')
  } finally {
    loading.value = false
  }
}

// 获取内容文件数据
// 替换原有的 fetchContentFile 函数
const fetchContentFile = async (id) => {
  try {
    const url = `${API_BASE_URL}/knowledge-contents/${id}/download`
    console.log('【预览】开始请求文件数据:', url)
    
    const response = await axios.get(url, {
      responseType: 'blob',
      timeout: 30000,
      headers: {
        'Accept': '*/*',
        'Cache-Control': 'no-cache'
      }
    })
    
    console.log('【预览】文件数据响应:', {
      status: response.status,
      size: response.data.size,
      type: response.data.type
    })
    
    return response.data
  } catch (error) {
    console.error('【预览】获取文件数据失败:', {
      message: error.message,
      code: error.code,
      response: error.response ? {
        status: error.response.status,
        data: error.response.data
      } : null
    })
    
    // 检查是否是404错误，可能是API路径不对
    if (error.response && error.response.status === 404) {
      ElMessage.warning('文件下载接口可能不正确，请检查后端API')
    }
    
    throw error
  }
}

// 处理预览数据
// 替换原有的 processPreviewData 函数
const processPreviewData = (data, fileBlob = null) => {
  const previewData = { ...data }
  
  // 统一类型字段
  previewData.type = data.contentType
  
  // 处理基础URL - 确保使用完整URL
  const baseUrl = `${API_BASE_URL}`
  
  // 处理视频类型
  if (data.contentType === 'video') {
    // 优先使用文件Blob（如果存在）
    if (fileBlob) {
      previewData.videoUrl = URL.createObjectURL(fileBlob)
    } 
    // 否则使用后端返回的fileUrl
    else if (data.fileUrl) {
      // 确保是完整的URL
      previewData.videoUrl = data.fileUrl.startsWith('http') 
        ? data.fileUrl 
        : `${baseUrl}${data.fileUrl.startsWith('/') ? '' : '/'}${data.fileUrl}`
    } else {
      previewData.videoUrl = ''
    }
    
    // 处理封面图
    if (data.coverUrl) {
      previewData.coverUrl = data.coverUrl.startsWith('http') 
        ? data.coverUrl 
        : `${baseUrl}${data.coverUrl.startsWith('/') ? '' : '/'}${data.coverUrl}`
    } else {
      previewData.coverUrl = ''
    }
  }
  // 处理文档类型
  else if (data.contentType === 'document') {
    // 确保是完整的URL
    if (data.fileUrl) {
      const fullFileUrl = data.fileUrl.startsWith('http') 
        ? data.fileUrl 
        : `${baseUrl}${data.fileUrl.startsWith('/') ? '' : '/'}${data.fileUrl}`
      
      // ====== 保存原始文件URL和文件名 ======
      previewData.fileUrl = fullFileUrl;
      previewData.fileName = fullFileUrl.split('/').pop();
      
      // 添加对文本文件(.txt, .md)的特殊处理
      if (fullFileUrl.match(/\.(txt|md)$/)) {
        // 如果有文件Blob，尝试读取内容
        if (fileBlob) {
          const reader = new FileReader();
          reader.onload = function(e) {
            previewData.textContent = e.target.result;
          }
          reader.readAsText(fileBlob);
        }
        // 如果没有文件Blob但有textContent，直接显示
        else if (data.textContent) {
          previewData.textContent = data.textContent;
        }
        // 设置一个标志表示这是文本文件
        previewData.isTextFile = true;
      }

      // 使用Office Online Viewer预览Office文档
      if (fullFileUrl.match(/\.(doc|docx|ppt|pptx)$/)) {
        previewData.documentUrl = `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(fullFileUrl)}`
      } 
      // PDF直接显示
      else if (fullFileUrl.endsWith('.pdf')) {
        previewData.documentUrl = fullFileUrl
      }
      // 其他文档类型
      else {
        previewData.documentUrl = fullFileUrl
      }
    } else {
      previewData.documentUrl = ''
    }
  }

  // 处理图片类型
  else if (data.contentType === 'image') {
    // 优先使用文件Blob（如果存在）
    if (fileBlob) {
      previewData.images = [URL.createObjectURL(fileBlob)]
    } 
    // 否则使用后端返回的fileUrl
    else if (data.fileUrl) {
      const fullFileUrl = data.fileUrl.startsWith('http') 
        ? data.fileUrl 
        : `${baseUrl}${data.fileUrl.startsWith('/') ? '' : '/'}${data.fileUrl}`
      previewData.images = [fullFileUrl]
    } else {
      previewData.images = []
    }
  }
  // 处理问答题类型
  else if (data.contentType === 'quiz') {
    // 确保选项数组存在且不为空
    previewData.options = data.options && data.options.length > 0 
      ? data.options 
      : ['', '', '', '']
    
    // 确保正确答案在有效范围内
    if (previewData.correctAnswer >= previewData.options.length) {
      previewData.correctAnswer = 0
    }
    
    // 处理解析内容
    if (!previewData.explanation) {
      previewData.explanation = '暂无解析'
    }
    
    // 如果没有结构化数据，尝试从textContent解析
    // 如果没有结构化数据，尝试从textContent解析
if (!data.question || !data.options || data.options.length === 0) {
  if (data.textContent) {
    try {
      const lines = data.textContent.split('\n');
      const questionMatch = lines[0].match(/题目：(.+)/);
      const optionsMatch = lines[1].match(/选项：(.+)/);
      const correctAnswerMatch = lines[2].match(/正确答案：(.+)/);
      const explanationMatch = lines[3].match(/解析：(.+)/);
      
      previewData.question = questionMatch ? questionMatch[1] : data.question || '';
      previewData.options = optionsMatch ? optionsMatch[1].split('； ') : data.options || [];
      previewData.explanation = explanationMatch ? explanationMatch[1] : data.explanation || '';
      
      // 修复：从解析的正确答案文本获取索引
      if (correctAnswerMatch && optionsMatch) {
        const correctAnswerText = correctAnswerMatch[1].trim();
        const options = optionsMatch[1].split('； ');
        
        // 在选项中查找匹配项（忽略大小写和空格）
        const correctIndex = options.findIndex(opt => 
          opt.trim().toLowerCase() === correctAnswerText.trim().toLowerCase()
        );
        
        // 如果找到匹配项，使用该索引
        if (correctIndex !== -1) {
          previewData.correctAnswer = correctIndex;
        } else {
          // 找不到匹配项时使用后端提供的值或默认值
          previewData.correctAnswer = data.correctAnswer !== undefined ? data.correctAnswer : 0;
        }
      } else {
        // 没有解析出正确答案文本时
        previewData.correctAnswer = data.correctAnswer !== undefined ? data.correctAnswer : 0;
      }
    } catch (e) {
      console.error('Quiz data parse error:', e);
      previewData.correctAnswer = 0;
    }
  }
}
  }
  
  // 添加空数据处理
  if (!previewData.title) {
    previewData.title = '未命名内容'
  }
  if (!previewData.description) {
    previewData.description = '暂无描述'
  }
  
  console.log('【预览】处理后的预览数据:', previewData)
  return previewData
}

// 添加文档下载功能
const downloadDocument = async (id) => {
  try {
    const response = await axios.get(`${API_BASE_URL}/knowledge-contents/${id}/download`, {
      responseType: 'blob',
      headers: {
        'Accept': '*/*'
      }
    });
    
    
    // 1. 从Content-Disposition头获取文件名
    let fileName = 'document';
    const contentDisposition = response.headers['content-disposition'];
    
    if (contentDisposition) {
      const parsedName = parseFileNameFromHeader(contentDisposition);
      if (parsedName) {
        fileName = parsedName;
      }
    }
    
    // 2. 如果仍无有效文件名，尝试从已知数据获取
    if (fileName === 'document' || !fileName.includes('.')) {
      // 从previewContent获取文件信息
      if (previewContent.value.fileName) {
        fileName = previewContent.value.fileName;
      }
      // 从标题生成文件名
      else if (previewContent.value.title) {
        fileName = previewContent.value.title;
      }
    }
    
    // 3. 确保文件名有正确的扩展名
    const contentType = response.headers['content-type'];
    if (contentType) {
      fileName = ensureFileExtension(fileName, contentType);
    }
    
    // 4. 创建下载链接
    const url = window.URL.createObjectURL(response.data);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', fileName);
    
    document.body.appendChild(link);
    link.click();
    
    // 5. 清理资源
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
    
    ElMessage.success(`已下载: ${fileName}`);
    
  } catch (error) {
    console.error('【下载】详细错误:', error);
    
    // 6. 备用下载方案
    try {
      // 直接使用URL下载（浏览器会处理文件名）
      const fallbackUrl = `${API_BASE_URL}/knowledge-contents/${id}/download`;
      const link = document.createElement('a');
      link.href = fallbackUrl;
      
      // 尝试设置一个合理的文件名
      let fallbackFileName = 'document';
      if (previewContent.value.title) {
        fallbackFileName = previewContent.value.title;
      }
      
      // 添加基于内容类型的扩展名
      if (previewContent.value.fileUrl) {
        const ext = previewContent.value.fileUrl.split('.').pop();
        if (ext && ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'txt', 'md'].includes(ext.toLowerCase())) {
          fallbackFileName += `.${ext}`;
        }
      }
      
      link.setAttribute('download', fallbackFileName);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      ElMessage.warning(`已尝试使用备用方案下载: ${fallbackFileName}`);
    } catch (fallbackError) {
      ElMessage.error('下载失败，请检查网络连接或联系管理员');
    }
  }
};

// 媒体加载错误处理
const handleMediaError = (type) => {
  let errorMsg = '';
  if (type === 'video') {
    errorMsg = '视频';
  } else if (type === 'document') {
    errorMsg = '文档';
    // 添加Office Online Viewer限制提示
    if (previewContent.value.documentUrl && previewContent.value.documentUrl.includes('officeapps.live.com')) {
      errorMsg += '（Office Online Viewer可能不支持此文件格式或大小）';
    }
  }
  
  ElMessage.error({
    message: `${errorMsg}文件加载失败，请检查文件链接或尝试下载查看`,
    duration: 5000
  });
  
  console.error('【预览】媒体加载错误详情:', {
    type,
    documentUrl: previewContent.value.documentUrl,
    fileUrl: previewContent.value.fileUrl
  });
};

// 图片加载错误处理
const handleImageError = (event) => {
  event.target.src = '/default-image.png' // 替换为默认图片路径
  ElMessage.warning('图片加载失败，已显示默认图片')
}

// 问答题答案检查
const checkAnswer = (selectedOptionIndex) => {
  // 验证参数有效性
  console.log('【预览】检查答案参数:', selectedOptionIndex)
  if (selectedOptionIndex === null || selectedOptionIndex === undefined) {
    ElMessage.warning('请选择一个答案')
    return
  }
  
  // 确保 previewContent 数据完整
  if (!previewContent.value || !previewContent.value.options || 
      !previewContent.value.options.length || previewContent.value.correctAnswer === undefined) {
    ElMessage.error('题目数据不完整')
    return
  }
  
  // 获取用户选择的选项文本
  const userSelectedOptionText = previewContent.value.options[selectedOptionIndex]
  
  // 获取正确答案文本（通过索引获取）
  const correctOptionText = previewContent.value.options[previewContent.value.correctAnswer]

  console.log('【预览】用户选择的答案:', userSelectedOptionText)
  console.log('【预览】正确答案:', previewContent.value)
  
  // 进行严格的字符串比较（可选：添加trim()和toLowerCase()处理）
  // isCorrect.value = userSelectedOptionText === correctOptionText
  // 推荐：忽略前后空格和大小写
  isCorrect.value = userSelectedOptionText.trim().toLowerCase() === 
                   correctOptionText.trim().toLowerCase()
  
  showQuizResult.value = true
}

// 重置问答题
const resetQuiz = () => {
  selectedAnswer.value = null
  showQuizResult.value = false
}

// 删除内容
const deleteContent = async (content) => {
  ElMessageBox.confirm(
    `确定要删除「${content.title}」吗？`,
    '删除确认',
    {
      confirmButtonText: '确定删除',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      await axios.delete(`${API_BASE_URL}/knowledge-contents/delete/${content.contentId}`)
      const index = contentList.value.findIndex(item => item.contentId === content.contentId)
      if (index !== -1) {
        contentList.value.splice(index, 1)
        totalItems.value--
      }
      ElMessage.success('内容已删除')
    } catch (error) {
      ElMessage.error('删除失败')
    }
  }).catch(() => {})
}

// ================== 分类操作 ==================
const addCategory = () => {
  isEdit.value = false
  categoryForm.categoryName = ''
  categoryForm.itemCount = 0
  categoryDialogVisible.value = true
}

const saveCategory = async () => {
  if (!categoryForm.categoryName.trim()) {
    ElMessage.warning('请输入分类名称')
    return
  }
  try {
    const response = await axios.post(`${API_BASE_URL}/knowledge-categories/add`, categoryForm)
    ElMessage.success('分类已添加')
    categoryDialogVisible.value = false
    fetchCategories()
  } catch (error) {
    ElMessage.error('保存分类失败')
  }
}

// ================== 内容类型辅助方法 ==================
const getContentTypeName = (type) => {
  switch (type) {
    case 'video': return '视频'
    case 'document': return '文本'
    case 'image': return '图片'
    case 'quiz': return '问答题'
    default: return '未知'
  }
}

const getContentTypeTag = (type) => {
  switch (type) {
    case 'video': return 'primary'
    case 'document': return 'success'
    case 'image': return 'warning'
    case 'quiz': return 'danger'
    default: return 'info'
  }
} 

// ================== 分页与筛选 ==================
const handleCategorySelect = (index) => {
  activeCategory.value = index
  fetchContentList()
}

const handleSizeChange = (val) => {
  pageSize.value = val
  fetchContentList()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchContentList()
}

watch(contentType, () => {
  fetchContentList()
})

// ================== 数据获取 ==================
const fetchCategories = async () => {
  try {
    const response = await axios.get(`${API_BASE_URL}/knowledge-categories/list`)
    categories.value = response.data.data
  } catch (error) {
    ElMessage.error('获取分类失败')
  }
}

const fetchContentList = async () => {
  if (!activeCategory.value) {
    ElMessage.warning('请选择有效分类')
    return
  }
  
  loading.value = true
  try {
    // 关键修改：使用后端期望的参数名
    const params = {
      categoryId: activeCategory.value,
      page: currentPage.value,  // 可能需要改为 page 而不是 pageNum
      size: pageSize.value,     // 可能需要改为 size 而不是 pageSize
      contentType: contentType.value
    }
    
    // 添加调试日志
    console.log('【分页】请求参数:', params)
    
    const response = await axios.get(`${API_BASE_URL}/knowledge-contents/page/${activeCategory.value}`, { 
      params,
      timeout: 15000
    })
    
    console.log('【分页】响应数据:', response.data)
    
    if (response.data.code === 1 && response.data.data) {
      contentList.value = response.data.data.rows
      totalItems.value = response.data.data.total
      
      // 添加数据验证
      if (currentPage.value > 1 && response.data.data.rows.length === 0) {
        ElMessage.warning(`第 ${currentPage.value} 页没有数据，请检查分页参数或数据量`)
      }
    } else {
      throw new Error(response.data.message || '数据格式异常')
    }
  } catch (error) {
    console.error('分页查询失败:', error)
    ElMessage.error(`加载失败: ${error.message || '请检查网络或联系管理员'}`)
    contentList.value = []
    totalItems.value = 0
  } finally {
    loading.value = false
  }
}

// ================== 生命周期 ==================
onMounted(async () => {
  await fetchCategories()
  fetchContentList()
})
</script>

<style scoped>
.knowledge-container {
  padding: 10px;
}

.category-card,
.content-card {
  height: calc(100vh - 100px);
  overflow: auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-left {
  display: flex;
  align-items: center;
}

.count-tag {
  margin-left: 10px;
}

.header-operations {
  display: flex;
  align-items: center;
}

.category-menu {
  border-right: none;
}

.item-count {
  margin-left: 5px;
  color: #909399;
  font-size: 12px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.option-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.option-item .el-radio {
  margin-right: 10px;
  width: 100px;
}

.option-item .el-input {
  flex: 1;
  margin-right: 10px;
}

.preview-container {
  padding: 10px;
}

.video-container,
.document-container {
  width: 100%;
  height: 450px;
  margin-bottom: 20px;
}

.preview-video,
.preview-document {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.quiz-container {
  margin-bottom: 20px;
}

.quiz-question {
  margin-top: 0;
  margin-bottom: 20px;
}

.quiz-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
}

.quiz-result {
  margin: 20px 0;
  padding: 15px;
  border-radius: 4px;
}

.result-message {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}

.correct {
  color: #67C23A;
}

.incorrect {
  color: #F56C6C;
}

.explanation {
  background-color: #f8f9fa;
  padding: 10px;
  border-radius: 4px;
}

.preview-info {
  margin-top: 20px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 4px;
}

.no-document {
  padding: 20px;
  background: #f5f7fa;
  border-radius: 4px;
}

.text-content-preview {
  margin-top: 10px;
  padding: 10px;
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  white-space: pre-wrap;
  line-height: 1.5;
}

.video-container {
  display: flex;
  justify-content: center;
  align-items: center;
  background: #000;
  border-radius: 4px;
  overflow: hidden;
}
</style>